const {time} = loader('fun');
//这个密钥很重要，建议自己打乱下方密钥的顺序防止破解
const data = ".qwtyui4jbsWERTYc9oeSAZXCVBNM1x6pafF2k3QOPLghzDUId0r5nm8l7vKJHG";

//获取cookie
exports.get=(key,cookie=pars())=>{
  if(key===undefined)return cookie;
  return cookie[key];
}
exports.set=(name,value,obj,data=[])=>{
  if(typeof name == 'string'){data.push({name,value,...obj})} else data=name;
  data.forEach((e,index)=>{
    let {name,value,httpOnly="httpOnly=httpOnly",path="/",time} = e;
    time?(expires_time(time)):(time=expires_time());
    (httpOnly==='none' || httpOnly==='') && (httpOnly='')
    data[index]=`${name}=${encryption(value)};${httpOnly};path=${path};expires=${time};`;
    data[index]=data[index].replace(/;;/g,";");
  })
  async_global.res.setHeader('Set-Cookie',data);
};

//解析出请求头中的cookie
function pars(cookie={}){
  async_global.req.headers.cookie.split(/; /g).filter(e=>e).forEach(e => {
    let a = e.split("=");
    let value = decryption(a[1]);
    cookie[a[0]]=value?value:a[1];  
  });
  return cookie;
}


//设置cook的时间
function expires_time(times=(time()+(1000*60*60*24))){
  return (new Date(times)).toUTCString();
}

//cookie加密
exports.encryption = encryption;
function encryption(str){
  if(str===undefined){new Error('加密内容为空')}
  str = jam(str+"");
  return "gem."+str;
}



//cookie解密
exports.decryption = decryption;
function decryption(str){
  //先判断是否为框架加密的cookie
  if(str.startsWith("gem.")){
    str = str.substring(4)
  }else{return str}
  return jem(str)
}

function jam(str){
  //把字符串转化为数字
  str = Array.from(conversionNuber(str+""));
  //获取随机字符串
  let key= randomString(8);
  let keys = key;
  //把字符串转化为数字
  key = conversionNuber(key,false);
  while (str.length>key.length)key+=key;
  //---------------------------------------------------
  //这时已经得到了两串数字，接下来将根据两串数字加密
  for (let i in str){
    str[i] = add(str[i],key[i]);
  }
  //加密完成
  return keys+"."+str.join("");
}

function jem(str,key){
  //解析
  key = conversionNuber(str.substring(0,str.indexOf(".")),false);
  str =Array.from(str.substring(str.indexOf(".")+1))
  while (str.length>key.length)key+=key;
  //---------------------------------------------------
  for (let i in str){
    str[i] = subtractingThe(str[i],key[i]);
  }
  //从数字转换为字符串
  return reduction(str.join(""))

}


//获取随机字符串
function randomString(len) {
  len = len || 32;
  let maxPos = data.length;
  let pwd = '';
  for (let i = 0; i < len; i++) {
    pwd += data.charAt(Math.floor(Math.random() * maxPos));
  }
  return pwd;
}

//转化为数字
function conversionNuber(str){
  return Array.from(Buffer.from(str+="").toString('hex')).map(e=>{
    let a = data.indexOf(e);
    //位置小于10补一个0
    return (a<10)?("0"+a):a;
  }).join("")
}

//两数字相加
function add(a=0,b=0){
  a = (a*1)+(b*1);
  a>=10 && (a=a-10);
  return a;
}
//两数字相加减
function subtractingThe(a=0,b=0){
  a<b && (a=a*1+10)
  return a-b;
}

//还原成字符串
function reduction(str) {
  //把所有数字每两个分为1组strkey
  let key = str.match(/[0-9]{2}/g).map(e => {
    //如果第一个数字是0，说明位置是小于10 ,然后到相应的位置拿数据
    e[0] === '0' && (e = e[1])
    return data[e];
  })
  return Buffer.from(key.join(""), 'hex').toString();
}